from fastapi import APIRouter

from apis_module.jsonvo.login_vo import Token
from apis_module.service.login_service import *
from config.env import JwtConfig
from config.get_db import get_db
from utils.response_util import *

loginMapping = APIRouter()


@loginMapping.post("/login", response_model=Token)
async def login(request: Request, login_data: AuthLoginModel,
                query_db: Session = Depends(get_db)):
    user = UserLogin(
        **dict(
            student_no=login_data.username,
            password=login_data.password
        )
    )
    try:
        result = await authenticate_user(request, query_db, user)
    except LoginException as e:
        return response_400(data="", message=e.message)

    try:
        access_token_expires = timedelta(minutes=JwtConfig.ACCESS_TOKEN_EXPIRE_MINUTES)
        session_id = str(uuid.uuid4())
        access_token = create_access_token(
            data={
                "user_id": result.student_so,
                "session_id": session_id,
            },
            expires_delta=access_token_expires
        )
        await request.app.state.redis.set(f'access_token:{session_id}', access_token,
                                          ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES))

        logger.info('登录成功')
        # 判断请求是否来自于api文档，如果是返回指定格式的结果，用于修复api文档认证成功后token显示undefined的bug
        request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get(
            'referer') else False
        request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get(
            'referer') else False
        if request_from_swagger or request_from_redoc:
            return {'access_token': access_token, 'token_type': 'Bearer', 'user_id': result.user_id}
        return response_200(
            data={'access_token': access_token, 'token_type': 'Bearer', 'user_id': result.user_id},
            message='登录成功'
        )
    except Exception as e:
        logger.exception(e)
        return response_500(data="", message='服务器异常，请联系管理员')
